<?php

namespace app\adminapi\service\tools;

use app\common\cache\FileCache;

class BuildLangService
{

    // 标记
    protected $flag;

    // 项目根目录
    protected $rootPath;

    // 生成文件路径
    protected $buildPath;

    // runtime目录
    protected $runtimePath;

    // 压缩包名称
    protected $zipTempName;

    // 压缩包临时路径
    protected $zipTempPath;

    public function __construct()
    {
        $this->rootPath = base_path() . '/';
        $this->runtimePath = $this->rootPath . 'runtime/';
        $this->buildPath = $this->rootPath . 'runtime/lang_pack/';
    }

    /**
     * 设置生成状态
     * @param $name
     * @param $status
     * @return void
     */
    public function setBuildFlag($name, $status = false)
    {
        $this->flag = $name;
        (new FileCache)->setFile($name, (int)$status, 3600);
    }

    /**
     * 获取生成状态标记
     * @return mixed
     */
    public function getBuildFlag()
    {
        return (new FileCache)->getFile($this->flag);
    }

    /**
     * @notes 删除标记时间
     */
    public function delBuildFlag()
    {
        return (new FileCache)->deleteFile($this->flag);
    }


    /**
     * @notes 删除生成文件夹内容
     */
    public function delBuildDirContent()
    {
        // 删除runtime目录制定文件夹
        !is_dir($this->buildPath) && mkdir($this->buildPath, 0755, true);
        del_target_dir($this->buildPath, false);
    }


    /**
     * @notes 文件夹不存在则创建
     * @param string $path
     */
    public function checkDir(string $path)
    {
        !is_dir($path) && mkdir($path, 0755, true);
    }

    /**
     * @notes 获取文件生成到runtime的文件夹路径
     * @return string
     */
    public function getRuntimeBuildDir($path = '')
    {
        $dir = $this->buildPath . $path;
        $this->checkDir($dir);
        return $dir;
    }

    /**
     * @notes 根据客户端类型_语言获取对应数组
     * @param array $sourceData
     * @param int $clientId
     * @param int $langId
     * @return array
     */
    public function getLangData(array $sourceData, int $clientId, int $langTypeId)
    {
        $data = [];
        foreach ($sourceData as $item) {
            if ($item['client_id'] === $clientId && $item['type_id'] === $langTypeId) {
                $data[$item['code']] = $item['after_text'];
            }
        }
        return $data;
    }

    /**
     * 转为json文件内容
     * @param array $data
     * @return string
     */
    public function translateToJSON(array $data)
    {
        $contentStr = "{ \r\n";
        foreach ($data as $key => $after_text) {
            $contentStr .= "\"" . $key . "\":\"" . $after_text . "\",\r\n";
        }
        $contentStr = rtrim($contentStr, ",\r\n") . "\r\n}";
        return $contentStr;
    }


    /**
     * 转为php文件内容
     * @param array $data
     * @return string
     */
    public function translateToPHP(array $data)
    {
        $contentStr = "<?php\r\n";
        $contentStr .= "return [\r\n";
        foreach ($data as $key => $after_text) {
            $contentStr .= '"' . $key . '"=>"' . $after_text . '"' . ",\r\n";
        }
        $contentStr .= "];";
        return $contentStr;
    }

    /**
     * @notes 生成静态资源
     * @param $langTypeItem
     * @param $clientItem
     * @param $translateData
     * @return true
     */
    public function buildLangCodeStasic($langTypeItem, $clientItem, $translateData)
    {
        $fileName = $langTypeItem['file_name'];
        if ($clientItem['type'] === 'php') {
            $filePath = $this->getRuntimeBuildDir($clientItem['path'] . str_replace('-', '_', $fileName)) . '/message.php';
            $translateData = $this->translateToPHP($translateData);
        } else {
            $filePath = $this->getRuntimeBuildDir($clientItem['path']) . '/' . $fileName . '.json';
            $translateData = $this->translateToJSON($translateData);
        }
        file_put_contents($filePath, $translateData);
        return true;
    }

    /**
     * @notes 压缩文件
     */
    public function zipFile()
    {
        $fileName = 'lang_pack' . date('YmdHis') . '.zip';
        $this->zipTempName = $fileName;
        $this->zipTempPath = $this->buildPath . $fileName;
        $zip = new \ZipArchive();
        $zip->open($this->zipTempPath, \ZipArchive::CREATE);
        $this->addFileZip($this->runtimePath, 'lang_pack', $zip);
        $zip->close();
    }


    /**
     * @notes 往压缩包写入文件
     * @param $basePath
     * @param $dirName
     * @param $zip
     */
    public function addFileZip($basePath, $dirName, $zip)
    {
        $handler = opendir($basePath . $dirName);
        while (($filename = readdir($handler)) !== false) {
            if ($filename != '.' && $filename != '..') {
                if (is_dir($basePath . $dirName . '/' . $filename)) {
                    // 当前路径是文件夹
                    $this->addFileZip($basePath, $dirName . '/' . $filename, $zip);
                } else {
                    // 写入文件到压缩包
                    $zip->addFile($basePath . $dirName . '/' . $filename, $dirName . '/' . $filename);
                }
            }
        }
        closedir($handler);
    }


    /**
     * @notes 返回压缩包临时路径
     * @return mixed
     */
    public function getDownloadUrl()
    {
        (new FileCache)->setFile($this->zipTempName, $this->zipTempName, 3600);
        return '//' . request()->host() . "/adminapi/setting/lang/translate/download?file=" . $this->zipTempName;
    }

}